<?php


namespace platform\controllers;

use Yii;
use yii\base\Model;
use yii\filters\Cors;
use yii\helpers\Json;
use yii\rest\ActiveController;
use yii\data\ActiveDataProvider;
use yii\filters\auth\HttpBearerAuth;
use yii\web\ForbiddenHttpException;

class BaseController extends ActiveController
{
    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];

    public $enableCsrfValidation = false;

    public function behaviors()
    {
        $behaviors = parent::behaviors();
        unset($behaviors['authenticator']);

        $behaviors['corsFilter'] = [
            'class' => Cors::className(),
            'cors' => [
                'Origin' => ['*'],
                'Access-Control-Request-Method' => ['*'],
                'Access-Control-Request-Headers' => ['*'],
                'Access-Control-Allow-Credentials' => null,
                'Access-Control-Max-Age' => 86400,
                'Access-Control-Expose-Headers' => [],
            ]
        ];
        if (Yii::$app->getRequest()->getMethod() !== 'OPTIONS') {
            $behaviors['authenticator'] = [
                'class' => HttpBearerAuth::className(),
                'optional' => $this->allowAction(),
                'except' => ['options']
            ];

            $behaviors['access'] = [
                'class' => 'platform\components\AccessControl',
            ];
        }


        return $behaviors;
    }

    public function beforeAction($action)
    {
        $queryParams = Yii::$app->request->getQueryParams();

        if (isset($queryParams['filter'])) {
            $queryParams['filter'] = Json::decode($queryParams['filter']);
        }

        Yii::$app->request->setQueryParams($queryParams);

        return parent::beforeAction($action);
    }

    public function actions()
    {
        $actions = parent::actions();

        $actions['index']['dataFilter'] = [
            'class' => \yii\data\ActiveDataFilter::class,
            'searchModel' => [
                'class' => $this->modelClass,
                'scenario' => 'search'
            ]
        ];

        // 使用 "prepareDataProvider()" 方法自定义数据 provider
        $actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];

        $scenario = \Yii::$app->request->get('scenario', Model::SCENARIO_DEFAULT);
        $actions['create']['scenario'] = $scenario;
        $actions['update']['scenario'] = $scenario;

        return $actions;
    }

    /**
     * 不需要登陆以及权限验证的action
     * @return array
     */
    public function allowAction()
    {
        return [];
    }


    public function prepareDataProvider($action, $filter)
    {
        $requestParams = Yii::$app->getRequest()->getBodyParams();
        if (empty($requestParams)) {
            $requestParams = Yii::$app->getRequest()->getQueryParams();
        }

        /* @var $modelClass \yii\db\BaseActiveRecord */
        $modelClass = $action->modelClass;

        $query = $modelClass::find();
        if (!empty($filter)) {
            $query->andFilterWhere($filter);
        }

        $activeDataProvider = [
            'class' => ActiveDataProvider::className(),
            'query' => $query,
            'pagination' => [
                'params' => $requestParams,
                'pageSizeLimit' => [0, 1000]
            ],
            'sort' => [
                'params' => $requestParams,
                'defaultOrder' => [
                    'sort' => SORT_DESC,
                    'id' => SORT_DESC
                ]
            ],
        ];

        if (!(new $this->modelClass)->hasAttribute('sort')) {
            unset($activeDataProvider['sort']['defaultOrder']['sort']);
        }

        return Yii::createObject($activeDataProvider);
    }
}
